/* vim: set sw=8 ts=8 sts=8 expandtab: */
#ifndef CMAID_SET_FUNCDEF_H
#define CMAID_SET_FUNCDEF_H

/**
 * @def CMAID_SET_FUNC(c)
 * @ingroup Cmaid_Set_Interface
 * Macro to access the set interface.
 */
#define CMAID_SET_FUNC(c) ((const Cmaid_Set_Interface *)(((c)->interface)))

/**
 * @param s the set to add an item
 * @param data; the data to add
 * @return Returns the adress of the element
 * @brief Adds an item to the set
 *
 * This function adds an item to the set given by the passed @p data. If there
 * is already an item equal to the given @p data, no item is added. No matter
 * if there was added a new item or not, the address returned points to the
 * item which is now or has been in the set. If the container allocates the
 * data for you, the pointer to the allocated address will be returned,
 */
CMAID_INLINE void *
cmaid_set_add(Cmaid_Set *s, const void *data)
{
        CMAID_CHECK_POINTER_RET(data, NULL);
        CMAID_CHECK_TYPE_RET(s, CMAID_MAGIC_SET, NULL);
        return CMAID_SET_FUNC(s)->add(s, data);
}

/**
 * @param s the set to remove the item
 * @param data the item to remove
 * @return Returns no value
 * @brief Removes the given item from the set
 *
 * Rempves the item from the set if the container has allocated the memory the
 * memory of the item is afterwards not safe to read.
 */
CMAID_INLINE void
cmaid_set_remove(Cmaid_Set *s, const void *data)
{
        CMAID_CHECK_POINTER(data);
        CMAID_CHECK_TYPE(s, CMAID_MAGIC_SET);
        CMAID_SET_FUNC(s)->remove(s, data);
}

/**
 * @param s the set to find the item
 * @param data the item to be find
 * @return The found data, or @c NULL
 *
 * This function returns the address of the data belgonging to the found node
 * this doesn't have to be the same like the data passed to the function, if 
 * the container creates a copy of it.
 */
CMAID_INLINE void *
cmaid_set_get(Cmaid_Set *s, const void *data)
{
        CMAID_CHECK_POINTER_RET(data, NULL);
        CMAID_CHECK_TYPE_RET(s, CMAID_MAGIC_SET, NULL);
        return CMAID_SET_FUNC(s)->get(s, data);
}

#endif
